using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

namespace EchoFramework
{
    /// <summary>
    /// UIView管理类
    /// </summary>
    public class UIViewManager : Singleton<UIViewManager>
    {
        private Canvas canvas;
        private CanvasScaler canvasScaler;
        private Transform hudPanelTrans;
        private Transform dialogPanelTrans;
        private Transform gamePanelTrans;
        private Transform windowPanelTrans;
        private Transform floatPanelTrans;

        /// <summary>
        /// 已打开的界面
        /// </summary>
        private Dictionary<int, UIViewBase> openedViewDict;

        /// <summary>
        /// 初始化 找到UI关键的几个挂点
        /// </summary>
        public override void OnAwake()
        {
            base.OnAwake();
            openedViewDict = new Dictionary<int, UIViewBase>();

            canvas = transform.Find("Canvas").GetComponent<Canvas>();
            canvasScaler = transform.Find("Canvas").GetComponent<CanvasScaler>();
            hudPanelTrans = canvas.transform.Find("HudPanel");
            hudPanelTrans.ClearChildren();
            dialogPanelTrans = canvas.transform.Find("DialogPanel");
            dialogPanelTrans.ClearChildren();
            gamePanelTrans = canvas.transform.Find("GamePanel");
            gamePanelTrans.ClearChildren();
            windowPanelTrans = canvas.transform.Find("WindowPanel");
            windowPanelTrans.ClearChildren();
            floatPanelTrans = canvas.transform.Find("FloatPanel");
            floatPanelTrans.ClearChildren();
        }

        public override void OnStart(Action action = null)
        {
            base.OnStart(action);
            InitCanvasScale();
        }

        /// <summary>
        /// 初始化Canva比例
        /// </summary>
        private void InitCanvasScale()
        {
            float deviceWidth = Screen.width;
            float deviceHeight = Screen.height;
            // canvasScaler.referenceResolution = new Vector2(deviceWidth, deviceHeight);
            GameLogger.LogYellow($"设备屏幕比例：{deviceWidth}*{deviceHeight}");
        }

        public override void OnUpdate()
        {
            base.OnUpdate();
            foreach (KeyValuePair<int, UIViewBase> viewKeyValue in openedViewDict)
            {
                viewKeyValue.Value.OnUpdate();
            }
        }

        /// <summary>
        /// 打开界面
        /// </summary>
        /// <param name="viewID">界面ID，枚举类型</param>
        /// <param name="objs">可变参数</param>
        /// <returns>返回界面UIViewBase</returns>
        public UIViewBase OpenWindow(UIViewID viewID, params object[] objs)
        {
            return OpenWindow((int) viewID, objs);
        }

        /// <summary>
        /// 打开界面
        /// </summary>
        /// <param name="viewID">界面ID</param>
        /// <param name="objs">可变参数</param>
        /// <returns>返回界面UIViewBase</returns>
        public UIViewBase OpenWindow(int viewID, params object[] objs)
        {
            if (openedViewDict.ContainsKey(viewID))
            {
                GameLogger.LogError("界面ID：" + viewID + " 已是打开状态！");
                return openedViewDict[viewID];
            }

            UIViewCfg viewCfg = UIViewCfg.GetUIViewConfigByViewID(viewID);
            if (viewCfg == null)
            {
                GameLogger.LogError("找寻不到界面ID：" + viewID + " 对应的配置！");
                return null;
            }

            GameObject viewGo = AssetManager.Instance.LoadGameObject(viewCfg.ResPath);
            UIViewBase view = viewGo.GetComponent<UIViewBase>();
            view.SetViewConfig(viewCfg);
            //弹窗层级和浮窗层级由于可以同时存在多个，故不记录字典中
            if (viewCfg.PanelType != UIPanelType.WindowPanel &&
                viewCfg.PanelType != UIPanelType.FloatPanel)
            {
                openedViewDict.Add(viewID, view);
            }

            switch (viewCfg.PanelType)
            {
                case UIPanelType.HUDPanel:
                    view.transform.SetParent(hudPanelTrans, false);
                    break;
                case UIPanelType.DialogPanel:
                    view.transform.SetParent(dialogPanelTrans, false);
                    break;
                case UIPanelType.GamePanel:
                    view.transform.SetParent(gamePanelTrans, false);
                    break;
                case UIPanelType.WindowPanel:
                    view.transform.SetParent(windowPanelTrans, false);
                    break;
                case UIPanelType.FloatPanel:
                    view.transform.SetParent(floatPanelTrans, false);
                    break;
                default:
                    GameLogger.LogError("界面配置表参数PanelType为：" + (int) viewCfg.PanelType + " 没有对应的放置位置！");
                    break;
            }

            view.transform.SetAsLastSibling();
            view.OnAwake();
            view.OnStart(objs);
            return view;
        }

        /// <summary>
        /// 界面是否已打开
        /// </summary>
        public bool WindowIsOpened(UIViewID viewID)
        {
            return WindowIsOpened((int) viewID);
        }

        /// <summary>
        /// 界面是否已打开
        /// </summary>
        public bool WindowIsOpened(int viewID)
        {
            return openedViewDict.ContainsKey(viewID);
        }

        /// <summary>
        /// 依据输入的界面ID，返回UIViewBase
        /// </summary>
        public UIViewBase GetWindowByViewID(UIViewID viewID)
        {
            return GetWindowByViewID((int) viewID);
        }

        /// <summary>
        /// 依据输入的界面ID，返回UIViewBase
        /// </summary>
        public UIViewBase GetWindowByViewID(int viewID)
        {
            UIViewBase view = null;
            openedViewDict.TryGetValue(viewID, out view);
            return view;
        }

        /// <summary>
        /// 关闭界面
        /// </summary>
        public void CloseWindow(UIViewID viewID)
        {
            CloseWindow((int) viewID);
        }

        /// <summary>
        /// 关闭界面
        /// </summary>
        public void CloseWindow(int viewID)
        {
            UIViewBase view = GetWindowByViewID(viewID);
            if (view != null)
            {
                if (openedViewDict.ContainsKey(viewID))
                {
                    openedViewDict.Remove(viewID);
                }

                view.OnClose();
            }
        }
    }
}